import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 23735
 * Date: 2023-01-19
 * Time: 20:21
 */
public class SeleniumGrammar {
    public ChromeDriver driver;
    public SeleniumGrammar(){
        this.driver= new ChromeDriver();
    }

    /**
     * 元素操作
     * @throws InterruptedException
     */
    public void elementOperation() throws InterruptedException {
        driver.get("https://www.baidu.com/");
        // 选择元素
        WebElement ele=driver.findElement(By.cssSelector("#kw"));
        // 获取文本
        String text=driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")).getText();
        System.out.println("文本文档: "+text);
        // 获取按钮上的属性
        WebElement element=driver.findElement(By.cssSelector("#su"));
        System.out.println("属性: "+element.getAttribute("value"));
        // 模拟按键输入
        ele.sendKeys("selenium");
        // 强制等待
        Thread.sleep(2000);
        // 清除往对象输入的内容
        ele.clear();
        Thread.sleep(2000);
        // 重新输入
        ele.sendKeys("迪丽热巴");
        Thread.sleep(2000);
        // 点击按钮
        element.click();
        Thread.sleep(2000);
        driver.quit();
    }

    /**
     * 等待
     * @throws InterruptedException
     */
    public void waitOperation() throws InterruptedException {
        driver.get("https://www.baidu.com/");
        driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        // 强制等待
        Thread.sleep(3000);
        // 隐式等待
        // 指定时间内所有元素出现进行下一步, 没有出现就报错, 隐式等待贯穿整个生命周期
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
        // 显式等待 等待某个条件满足时进行下一步
        WebDriverWait wait=new WebDriverWait(driver, Duration.ofSeconds(2));
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")));
        // 注意隐式等待和显式等待不要同时使用, 否则出现意想不到的结果
        driver.quit();
    }

    /**
     * 信息打印
     */
    public void informationPrint() throws InterruptedException {
        driver.get("https://www.baidu.com/");
        // 打印标题
        String title=driver.getTitle();
        System.out.println("标题: "+title);
        // 打印当前 URL
        String curURL=driver.getCurrentUrl();
        System.out.println("当前 URL"+curURL);
        // 注意 selenium 不会根据当前标签页的变化, 更改获得的标题和URL
        driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        Thread.sleep(3000);
        // 打印标题
        title=driver.getTitle();
        System.out.println("跳转过之后的标题: "+title);
        // 打印当前 URL
        curURL=driver.getCurrentUrl();
        System.out.println("跳转过之后的URL"+curURL);
        driver.quit();
    }

    /**
     * 窗口操作
     * @throws InterruptedException
     */
    public void windowOperation() throws InterruptedException {
        driver.get("https://www.baidu.com/");
        // selenium 给每个标签页一个唯一的标识, 叫做 句柄
        // 获取当前页面的句柄
        String mark=driver.getWindowHandle();
        System.out.println("当前页面的句柄: "+mark);
        // 跳转到一个新的页面
        driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        mark=driver.getWindowHandle();
        System.out.println("跳转后的句柄: "+mark);
        // 获取所有页面的句柄
        System.out.println("所有页面的句柄");
        Set<String> marks=driver.getWindowHandles();
        for(String str: marks){
            System.out.println(str);
        }
        // 如何切换到最新的页面(这里只适用于只有两个标签页), 从所有的句柄中找到想要跳转的, 使用方法进行跳转
        for(String str: marks){
            if(!str.equals(mark)){
                // 切换到最新的页面
                driver.switchTo().window(str);
            }
        }
        // 获取新的句柄
        String curMark=driver.getWindowHandle();
        System.out.println("切换到新页面后的句柄"+curMark);

        // 窗口大小的设置
        // 最大化
        driver.manage().window().maximize();
        Thread.sleep(3000);
        //  最小化
        driver.manage().window().minimize();
        Thread.sleep(3000);
        // 设置指定大小
        driver.manage().window().setSize(new Dimension(100,400));
        Thread.sleep(3000);
        driver.quit();
    }

    /**
     * 导航前进 后退
     * @throws InterruptedException
     */
    public void navigateOperation() throws InterruptedException {
        driver.get("https://tool.lu/");
        driver.findElement(By.cssSelector("#page > div:nth-child(1) > div.tabs-wrap > ul > li:nth-child(2) > a")).click();
        // 后退
        driver.navigate().back();
        Thread.sleep(2000);
        // 前进
        driver.navigate().forward();
        Thread.sleep(2000);
        // 再来一次后退
        driver.navigate().back();
        Thread.sleep(2000);
        driver.quit();
    }

    /**
     * 弹窗操作
     */
    public void popUpWindow(){
        driver.get("");
        // 1. 警告弹窗 + 确认弹窗
        // 先切换到弹窗上
        Alert alert=driver.switchTo().alert();
        // 点击确认
        alert.accept();
        // 点击取消
        alert.dismiss();
        // 2. 提示弹窗(需要输入内容的那种)
        // 先切换到弹窗上
        Alert alert2=driver.switchTo().alert();
        alert2.sendKeys("要输入的字符串");
        // 确认
        alert2.accept();
        driver.quit();
    }

    /**
     * 鼠标键盘操作
     */
    public void mouseAndKeyboard() throws InterruptedException {
        driver.get("https://www.baidu.com/");
        // 鼠标
        WebElement ele=driver.findElement(By.cssSelector("#hotsearch-refresh-btn > span"));
        Actions action=new Actions(driver);
        // 先移动到元素上面 注意不 perform 是看不出来的
        action.clickAndHold(ele).perform();
        Thread.sleep(2000);
        // 点击指定元素
        action.click(ele).perform();
        Thread.sleep(2000);
        // 键盘
        WebElement element=driver.findElement(By.cssSelector("#kw"));
        element.sendKeys("迪丽热巴");
        Thread.sleep(2000);
        driver.quit();
    }

    /**
     * 下拉选择框操作
     */
    public void selectBox() throws InterruptedException {
        driver.get("chrome://settings/appearance");
        WebElement ele=driver.findElement(By.cssSelector("#dropdownMenu"));
        Select select=new Select(ele);
        // 根据 索引定位 下标从0开始
        select.selectByIndex(1);
        Thread.sleep(2000);
        // 根据可见的文本选择
        select.selectByVisibleText("中");
        Thread.sleep(2000);
        // 还可以根据 value 这个属性值进行选择, 但这个网站的前端代码中没有value 这个属性
        driver.quit();
    }

    /**
     * 文件上传
     * @throws InterruptedException
     */
    public void fileUpload() throws InterruptedException {
        driver.get("https://tool.lu/pdfmerger/");
        // 选到上传文件的那个元素
        WebElement ele=driver.findElement(By.xpath("//*[@id=\"app\"]/div/div[1]/div[1]/a"));
        // 直接sendKeys 使用文件路径即可
        ele.sendKeys("D:\\test.pdf");
        Thread.sleep(3000);
        driver.quit();
    }

    /**
     * 屏幕截图
     */
    public void screenPrint() throws InterruptedException, IOException {
        driver.get("https://www.baidu.com");
        driver.findElement(By.cssSelector("#kw")).sendKeys("selenium");
        driver.findElement(By.cssSelector("#su")).click();
        File scrFile=driver.getScreenshotAs(OutputType.FILE);
        File descFile=new File("./picture/screen2.png");
        FileUtils.copyFile(scrFile, descFile);
        driver.findElement(By.cssSelector("#\\31  > div > div > h3 > a"));
        driver.quit();
    }
}
